```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring Boot启动时执行代码的几种方式</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
        }
        .code-block {
            background-color: #1e293b;
            border-left: 4px solid #7c3aed;
        }
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
        }
        .mermaid {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero text-white py-20">
        <div class="container mx-auto px-6 text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-4">Spring Boot启动代码执行指南</h1>
            <p class="text-xl md:text-2xl mb-8">掌握应用初始化的五种优雅方式</p>
            <div class="flex justify-center">
                <div class="w-full md:w-3/4 lg:w-1/2 bg-white bg-opacity-20 backdrop-filter backdrop-blur-sm p-6 rounded-lg">
                    <p class="text-lg">在Spring Boot应用启动时执行特定代码是开发中的常见需求，本文详细介绍了五种实现方式，帮助你在应用启动完成后优雅地执行初始化任务或配置操作。</p>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto px-6 py-12">
        <div class="grid grid-cols-1 md:grid-cols-12 gap-8">
            <!-- Content -->
            <div class="md:col-span-8">
                <!-- Introduction -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card">
                    <h2 class="text-2xl font-bold mb-4 text-gray-800">引言</h2>
                    <p class="text-gray-700">在Spring Boot启动时执行特定的代码可以通过几种方式实现，这些方式可以帮助你在应用启动完成后立即执行一些初始化任务或配置操作。选择合适的初始化方式可以让你的应用更加健壮和易于维护。</p>
                </div>

                <!-- Method 1 -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card" id="method1">
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 text-indigo-600 rounded-full w-8 h-8 flex items-center justify-center mr-4">
                            <span class="font-bold">1</span>
                        </div>
                        <h2 class="text-2xl font-bold text-gray-800">使用 <code class="bg-indigo-100 text-indigo-600 px-2 py-1 rounded">CommandLineRunner</code> 接口</h2>
                    </div>
                    <p class="text-gray-700 mb-4"><code>CommandLineRunner</code> 是 Spring Boot 提供的一个接口，可以用来在应用启动后执行代码。它的 <code>run</code> 方法会在 Spring Boot 启动后立即调用。</p>
                    <div class="code-block rounded-lg p-4 mb-4">
                        <pre class="text-gray-300 overflow-x-auto"><code>import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class StartupRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // 在 Spring Boot 启动后执行的代码
        System.out.println("应用启动完成，执行初始化操作...");
    }
}</code></pre>
                    </div>
                    <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
                        <div class="flex">
                            <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-blue-500" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2h-1V9z" clip-rule="evenodd"></path>
                                </svg>
                            </div>
                            <div class="ml-3">
                                <p class="text-sm text-blue-700">这是Spring Boot中最常用的启动执行方式，适合简单的初始化任务，执行时机在应用上下文完全加载之后。</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Method 2 -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card" id="method2">
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 text-indigo-600 rounded-full w-8 h-8 flex items-center justify-center mr-4">
                            <span class="font-bold">2</span>
                        </div>
                        <h2 class="text-2xl font-bold text-gray-800">使用 <code class="bg-indigo-100 text-indigo-600 px-2 py-1 rounded">ApplicationRunner</code> 接口</h2>
                    </div>
                    <p class="text-gray-700 mb-4"><code>ApplicationRunner</code> 是另一个类似于 <code>CommandLineRunner</code> 的接口，但它的 <code>run</code> 方法接收 <code>ApplicationArguments</code> 参数。这对需要访问应用程序参数的情况很有用。</p>
                    <div class="code-block rounded-lg p-4 mb-4">
                        <pre class="text-gray-300 overflow-x-auto"><code>import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class StartupApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 在 Spring Boot 启动后执行的代码
        System.out.println("应用启动完成，执行初始化操作...");
    }
}</code></pre>
                    </div>
                    <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
                        <div class="flex">
                            <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-blue-500" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2h-1V9z" clip-rule="evenodd"></path>
                                </svg>
                            </div>
                            <div class="ml-3">
                                <p class="text-sm text-blue-700">当需要处理应用启动参数时，<code>ApplicationRunner</code>比<code>CommandLineRunner</code>更合适，因为它提供了更结构化的参数访问方式。</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Method 3 -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card" id="method3">
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 text-indigo-600 rounded-full w-8 h-8 flex items-center justify-center mr-4">
                            <span class="font-bold">3</span>
                        </div>
                        <h2 class="text-2xl font-bold text-gray-800">使用 <code class="bg-indigo-100 text-indigo-600 px-2 py-1 rounded">@PostConstruct</code> 注解</h2>
                    </div>
                    <p class="text-gray-700 mb-4"><code>@PostConstruct</code> 注解可以用于类中的初始化方法，这些方法会在 Spring 完成依赖注入后、Bean 完成初始化后被调用。</p>
                    <div class="code-block rounded-lg p-4 mb-4">
                        <pre class="text-gray-300 overflow-x-auto"><code>import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;

@Component
public class InitializationBean {

    @PostConstruct
    public void init() {
        // 在 Spring 完成依赖注入后执行的代码
        System.out.println("应用启动完成，执行初始化操作...");
    }
}</code></pre>
                    </div>
                    <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
                        <div class="flex">
                            <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-blue-500" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2h-1V9z" clip-rule="evenodd"></path>
                                </svg>
                            </div>
                            <div class="ml-3">
                                <p class="text-sm text-blue-700">注意：<code>@PostConstruct</code>方法的执行时机早于<code>CommandLineRunner</code>和<code>ApplicationRunner</code>，在Bean初始化阶段就会执行。</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Method 4 -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card" id="method4">
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 text-indigo-600 rounded-full w-8 h-8 flex items-center justify-center mr-4">
                            <span class="font-bold">4</span>
                        </div>
                        <h2 class="text-2xl font-bold text-gray-800">实现 <code class="bg-indigo-100 text-indigo-600 px-2 py-1 rounded">SpringApplicationListener</code> 接口</h2>
                    </div>
                    <p class="text-gray-700 mb-4">可以通过实现 <code>ApplicationListener</code> 接口来监听 Spring Boot 应用的启动事件，并在事件触发时执行特定代码。<code>ApplicationReadyEvent</code> 是应用准备好之后触发的事件，可以用来执行启动后的逻辑。</p>
                    <div class="code-block rounded-lg p-4 mb-4">
                        <pre class="text-gray-300 overflow-x-auto"><code>import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class ApplicationStartupListener implements ApplicationListener&lt;ApplicationReadyEvent&gt; {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // 在应用启动并准备好后执行的代码
        System.out.println("应用启动完成，执行初始化操作...");
    }
}</code></pre>
                    </div>
                    <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
                        <div class="flex">
                            <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-blue-500" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2h-1V9z" clip-rule="evenodd"></path>
                                </svg>
                            </div>
                            <div class="ml-3">
                                <p class="text-sm text-blue-700">这种方式可以监听Spring Boot的各种生命周期事件，适合需要在特定阶段执行代码的场景。</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Method 5 -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card" id="method5">
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 text-indigo-600 rounded-full w-8 h-8 flex items-center justify-center mr-4">
                            <span class="font-bold">5</span>
                        </div>
                        <h2 class="text-2xl font-bold text-gray-800">使用 <code class="bg-indigo-100 text-indigo-600 px-2 py-1 rounded">SmartLifecycle</code> 接口</h2>
                    </div>
                    <p class="text-gray-700 mb-4"><code>SmartLifecycle</code> 是一个更高级的生命周期接口，可以提供更灵活的控制。通过实现 <code>SmartLifecycle</code> 接口，可以在应用启动和停止时执行代码。</p>
                    <div class="code-block rounded-lg p-4 mb-4">
                        <pre class="text-gray-300 overflow-x-auto"><code>import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

@Component
public class MySmartLifecycle implements SmartLifecycle {

    private boolean running = false;

    @Override
    public void start() {
        // 在应用启动时执行的代码
        System.out.println("应用启动完成，执行初始化操作...");
        running = true;
    }

    @Override
    public void stop() {
        // 在应用停止时执行的代码
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    // 其他方法可以根据需要实现
}</code></pre>
                    </div>
                    <div class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
                        <div class="flex">
                            <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-blue-500" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2h-1V9z" clip-rule="evenodd"></path>
                                </svg>
                            </div>
                            <div class="ml-3">
                                <p class="text-sm text-blue-700"><code>SmartLifecycle</code>提供了最细粒度的控制，适合需要精确管理生命周期的高级场景。</p>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Summary -->
                <div class="bg-white rounded-lg shadow-lg p-8 mb-8 card">
                    <h2 class="text-2xl font-bold mb-6 text-gray-800">方法对比总结</h2>
                    <div class="overflow-x-auto">
                        <table class="min-w-full divide-y divide-gray-200">
                            <thead class="bg-gray-50">
                                <tr>
                                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">方法</th>
                                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">执行时机</th>
                                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">适用场景</th>
                                </tr>
                            </thead>
                            <tbody class="bg-white divide-y divide-gray-200">
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap"><code>CommandLineRunner</code></td>
                                    <td class="px-6 py-4 whitespace-nowrap">应用完全启动后</td>
                                    <td class="px-6 py-4">简单初始化任务</td>
                                </tr>
                                <tr class="bg-gray-50">
                                    <td class="px-6 py-4 whitespace-nowrap"><code>ApplicationRunner</code></td>
                                    <td class="px-6 py-4 whitespace-nowrap">应用完全启动后</td>
                                    <td class="px-6 py-4">需要处理启动参数的任务</td>
                                </tr>
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap"><code>@PostConstruct</code></td>
                                    <td class="px-6 py-4 whitespace-nowrap">Bean初始化完成时</td>
                                    <td class="px-6 py-4">Bean级别的初始化</td>
                                </tr>
                                <tr class="bg-gray-50">
                                    <td class="px-6 py-4 whitespace-nowrap"><code>ApplicationListener</code></td>
                                    <td class="px-6 py-4 whitespace-nowrap">特定事件触发时</td>
                                    <td class="px-6 py-4">基于事件驱动的初始化</td>
                                </tr>
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap"><code>SmartLifecycle</code></td>
                                    <td class="px-6 py-4 whitespace-nowrap">精确控制的生命周期阶段</td>
                                    <td class="px-6 py-4">需要精细控制的高级场景</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- Sidebar -->
            <div class="md:col-span-4">
                <!-- Quick Navigation -->
                <div class="bg-white rounded-lg shadow-lg p-6 mb-8 sticky top-4 card">
                    <h3 class="text-lg font-bold mb-4 text-gray-800">快速导航</h3>
                    <ul class="space-y-2">
                        <li><a href="#method1" class="flex items-center text-indigo-600 hover:text-indigo-800 transition-colors"><i class="fas fa-arrow-right mr-2 text-sm"></i> CommandLineRunner</a></li>
                        <li><a href="#method2" class="flex items-center text-indigo-600 hover:text-indigo-800 transition-colors"><i class="fas fa-arrow-right mr-2 text-sm"></i> ApplicationRunner</a></li>
                        <li><a href="#method3" class="flex items-center text-indigo-600 hover:text-indigo-800 transition-colors"><i class="fas fa-arrow-right mr-2 text-sm"></i> @PostConstruct</a></li>
                        <li><a href="#method4" class="flex items-center text-indigo-600 hover:text-indigo-800 transition-colors"><i class="fas fa-arrow-right mr-2 text-sm"></i> ApplicationListener</a></li>
                        <li><a href="#method5" class="flex items-center text-indigo-600 hover:text-indigo-800 transition-colors"><i class="fas fa-arrow-right mr-2 text-sm"></i> SmartLifecycle</a></li>
                    </ul>
                </div>

                <!-- Flow Chart -->
                <div class="bg-white rounded-lg shadow-lg p-6 mb-8 card">
                    <h3 class="text-lg font-bold mb-4 text-gray-800">执行时机流程图</h3>
                    <div class="mermaid">
                        flowchart TD
                            A[应用启动] --> B[Bean初始化]
                            B --> C[@PostConstruct执行]
                            C --> D[应用上下文加载完成]
                            D --> E[CommandLineRunner/ApplicationRunner执行]
                            D --> F[ApplicationReadyEvent触发]
                    </div>
                </div>

                <!-- Tips -->
                <div class="bg-white rounded-lg shadow-lg p-6 card">
                    <h3 class="text-lg font-bold mb-4 text-gray-800">最佳实践建议</h3>
                    <ul class="space-y-3">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span class="text-gray-700">对于简单的初始化任务，优先使用<code>CommandLineRunner</code>或<code>ApplicationRunner</code></span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span class="text-gray-700">需要处理Bean自身初始化时使用<code>@PostConstruct</code></span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span class="text-gray-700">需要监听特定事件时使用<code>ApplicationListener</code></span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span class="text-gray-700">需要精确控制生命周期时使用<code>SmartLifecycle</code></span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span class="text-gray-700">避免在初始化方法中执行耗时操作，考虑异步执行</span>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-8">
        <div class="container mx-auto px-6 text-center">
            <div class="flex justify-center space-x-4 mb-4">
                <a href="http://www.yuque.com/jtostring" class="hover:text-white transition-colors">
                    <i class="fas fa-book mr-2"></i>技术小馆
                </a>
                <span>|</span>
                <a href="http://www.yuque.com/jtostring" class="hover:text-white transition-colors">
                    <i class="fas fa-map-marker-alt mr-2"></i>技术小馆地址
                </a>
            </div>
            <p class="text-sm">© 2023 技术小馆. 保留所有权利.</p>
        </div>
    </footer>

    <script>
        // Initialize Mermaid
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```